package cn.wind.xboot.framework.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.input.TeeInputStream;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;

/**
 * <p>Title: RequestWrapper</p>
 * <p>Description: TODO</p>
 *
 * @author xukk
 * @version 1.0
 * @date 2018/8/9
 */
@Slf4j
class RequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params;

    private boolean isParams = false;

    private final ByteArrayOutputStream bos = new ByteArrayOutputStream();

    private long id;
    public RequestWrapper(Long requestId,HttpServletRequest request) {
        super(request);

        this.id = requestId;
    }
    public RequestWrapper(HttpServletRequest request,
                          Long requestId, Map<String, String[]> newParams) {
        super(request);

        this.id = requestId;

        this.params = newParams;

        this.isParams = true;
    }

    public RequestWrapper(HttpServletRequest request,
                          Map<String, String[]> newParams) {
        super(request);

        this.params = newParams;

        this.isParams = true;
    }

    @Override
    public String getParameter(String name) {
        if (isParams) {
            String result;
            Object v = params.get(name);
            if (v == null) {
                result = null;
            } else if (v instanceof String[]) {
                String[] strArr = (String[]) v;
                if (strArr.length > 0) {
                    result = strArr[0];
                } else {
                    result = null;
                }
            } else if (v instanceof String) {
                result = (String) v;
            } else {
                result = v.toString();
            }

            return result;
        } else {
            return super.getParameter(name);
        }

    }

    @Override
    public Map getParameterMap() {
        if (isParams) {
            return params;
        } else {
            return super.getParameterMap();
        }

    }

    @Override
    public Enumeration getParameterNames() {
        if (isParams) {
            return new Vector(params.keySet()).elements();
        } else {
            return super.getParameterNames();
        }

    }

    @Override
    public String[] getParameterValues(String name) {
        if (isParams) {
            String[] result;
            Object v = params.get(name);
            if (v == null) {
                result = null;
            } else if (v instanceof String[]) {
                result = (String[]) v;
            } else if (v instanceof String) {
                result = new String[]{(String) v};
            } else {
                result = new String[]{v.toString()};
            }

            return result;
        } else {
            return super.getParameterValues(name);
        }

    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            private TeeInputStream tee = new TeeInputStream(RequestWrapper.super.getInputStream(), bos);

            @Override
            public int read() throws IOException {
                return tee.read();
            }
        };

    }

    public byte[] toByteArray() {
        return bos.toByteArray();
    }

    public Long getId() {
        return id;
    }

}